home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -screenplay- / hd_installers / -whdload- / whdload_dev / src / sources / savegame.s < prev    next >
Text File  |  1998-07-16  |  15KB  |  746 lines

  1. ;*---------------------------------------------------------------------------
  2. ;  :Program.    savegame.s
  3. ;  :Contents.    routine for multiple save game support
  4. ;        it creates an interface from which the user can choice between
  5. ;        9 different savegames, a description can be entered for each
  6. ;        savegame, all savegames will be stored in one single file which
  7. ;        grows dynamically
  8. ;        the savegames must have always the same size
  9. ;  :Author.    Wepl
  10. ;  :Version.    $Id: savegame.s 1.1 1998/06/27 23:53:54 jah Exp jah $
  11. ;  :History.    14.06.98 extracted from Interphase slave
  12. ;        15.06.98 returncode fixed
  13. ;             problem with savegames larger than $7fff fixed
  14. ;  :Requires.    _keyexit    byte variable containing rawkey code
  15. ;        _exit        function to quit
  16. ;  :Copyright.    Public Domain
  17. ;  :Language.    68000 Assembler
  18. ;  :Translator.    Barfly V2.9
  19. ;  :To Do.
  20. ;---------------------------------------------------------------------------*
  21. ; this is a example sequence to use the savegame routine
  22. ; during execution some custom registers will be destroyed, if the installed
  23. ; program does not refresh them itself, it must be done after calling the
  24. ; savegame routine
  25.  
  26.     IFEQ 1
  27.  
  28.         move.l    #100,d0            ;savegame size
  29.         lea    $3e900,a0        ;address of savegame
  30.         lea    $65000,a1        ;free mem for screen
  31.         bsr    _sg_load
  32.     ;    move.w    #$4100,(_custom+bplcon0)
  33.     ;    move.w    #320/8*3,(_custom+bpl1mod)
  34.     ;    move.l    #$00000eee,(_custom+color)
  35.  
  36.     ENDC
  37.  
  38. ;--------------------------------
  39. ; IN:    d0 = ULONG size (only on function save required)
  40. ;    a0 = APTR  address of load/save area
  41. ;    a1 = APTR  space for the screen ($2800 bytes)
  42. ; OUT:    d0 = BOOL  success
  43. ;    d1/a0/a1 destroyed
  44.  
  45. MAXNAMELEN    = 40
  46. LINE        = 320/8
  47. SCREEN        = LINE*200
  48. SAVEDIRLEN    = 4+10+(10*MAXNAMELEN)
  49. CHARHEIGHT    = 5
  50. CHARWIDTH    = 5
  51.  
  52.     INCLUDE    macros/ntypes.i
  53.  
  54.     NSTRUCTURE    SaveGame,0
  55.         NLONG    sg_screen
  56.         NLONG    sg_size
  57.         NLONG    sg_address
  58.         NLONG    sg_old68
  59.         NLONG    sg_old6c
  60.         NWORD    sg_oldintena
  61.         NWORD    sg_olddmacon
  62.         NSTRUCT    sg_save_names,10*MAXNAMELEN
  63.         NSTRUCT    sg_save_flags,10
  64.         NSTRUCT    sg_save_id,4
  65.         NSTRUCT    sg_tmpname,MAXNAMELEN
  66.         NWORD    sg_c_x
  67.         NWORD    sg_c_y
  68.         NBYTE    sg_key
  69.         NBYTE    sg_c_on
  70.         NBYTE    sg_success
  71.         NALIGNLONG
  72.         NLABEL    sg_SIZEOF
  73.  
  74. ;--------------------------------
  75. ; print save game directory
  76. ; IN:    -
  77. ; OUT:    -
  78.  
  79. XBASE    = 50
  80. YBASE    = 40
  81. YSKIP    = 15
  82.  
  83. _sg_printdir    moveq    #XBASE,d0        ;x-pos
  84.         moveq    #YBASE-YSKIP,d1        ;first line
  85.         moveq    #'1',d2
  86.         moveq    #0,d3            ;amount saves
  87. .next        add.w    #YSKIP,d1        ;line skip
  88.         bsr    _pc
  89.         movem.l    d0/d2,-(a7)
  90.         add.w    #15,d0
  91.         sub.w    #'1',d2
  92.         mulu.w    #MAXNAMELEN,d2
  93.         lea    (sg_save_names,a5),a0
  94.         add.w    d2,a0
  95.         bsr    _ps
  96.         movem.l    (a7)+,d0/d2
  97.         addq.b    #1,d2
  98.         cmp.b    #'9',d2
  99.         bls    .next
  100.         rts
  101.  
  102. ;--------------------------------
  103. ; save a savegame
  104. ; IN:    D0 = size of the savegame
  105. ;    A0 = address to load savegame on
  106. ;    A1 = address of free memory for screen ($2800 bytes)
  107. ; OUT:    D0 = BOOL success
  108.  
  109. _sg_save    moveq    #0,d1
  110.         bra    _sg_degrade
  111. _sg_save_in    bsr    _sg_loaddir
  112.  
  113. .start        moveq    #7,d1
  114.         lea    _save,a0
  115.         bsr    _psc
  116.         add.w    #8,d1
  117.         lea    _saveselect,a0
  118.         bsr    _psc
  119.         add.w    #8,d1
  120.         lea    _esc,a0
  121.         bsr    _psc
  122.  
  123.         bsr    _sg_printdir
  124.  
  125. .keyloop    bsr    _sg_get_key
  126.         cmp.b    #$45,d0
  127.         beq    _sg_restore
  128.         
  129.         lea    (_keytrans),a0
  130.         move.b    (a0,d0.w),d1
  131.         cmp.b    #'1',d1
  132.         blo    .keyloop
  133.         cmp.b    #'9',d1
  134.         bhi    .keyloop
  135.         
  136.         moveq    #XBASE+9,d0
  137.         sub.w    #'1',d1
  138.         move.w    d1,d6            ;D6 = save no.
  139.         mulu    #YSKIP,d1
  140.         add.w    #YBASE-5,d1
  141.         move.w    d0,d2
  142.         add.w    #210,d2
  143.         move.w    d1,d3
  144.         add.w    #YSKIP-1,d3
  145.         bsr    _sg_rect
  146.         
  147.         move.w    d6,d0
  148.         mulu.w    #MAXNAMELEN,d0
  149.         lea    (sg_save_names,a5),a3
  150.         add.w    d0,a3            ;A3 = save name
  151.         
  152.         move.l    a3,a0
  153.         lea    (sg_tmpname,a5),a1
  154. .cpy        move.b    (a0)+,(a1)+
  155.         bne    .cpy
  156.  
  157. .chkname    moveq    #-1,d5
  158.         move.l    a3,a0
  159. .cnt        addq.w    #1,d5            ;D5 = charpos in save name
  160.         tst.b    (a0)+
  161.         bne    .cnt
  162.         
  163.         move.w    d5,d0
  164.         mulu    #CHARWIDTH,d0
  165.         add.w    #XBASE+15,d0
  166.         move.w    d0,(sg_c_x,a5)
  167.         move.w    d6,d1
  168.         mulu    #YSKIP,d1
  169.         add.w    #YBASE,d1
  170.         move.w    d1,(sg_c_y,a5)
  171.         st    (sg_c_on,a5)
  172.  
  173.         moveq    #15,d1
  174.         lea    _saveinsert,a0
  175.         bsr    _psc
  176.         
  177. .nextkey    bsr    _sg_get_key
  178.         cmp.b    #$43,d0            ;enter
  179.         beq    .return
  180.         cmp.b    #$44,d0            ;return
  181.         beq    .return
  182.         cmp.b    #$41,d0            ;backspace
  183.         beq    .bs
  184.         cmp.b    #$46,d0            ;delete
  185.         beq    .bs
  186.         cmp.b    #$45,d0            ;escape
  187.         beq    .esc
  188.         cmp.w    #MAXNAMELEN-1,d5
  189.         beq    .nextkey
  190.         lea    (_keytrans),a0
  191.         move.b    (a0,d0.w),d2
  192.         beq    .nextkey
  193.         move.b    d2,(a3,d5.w)
  194.         addq.w    #1,d5
  195.         move.w    (sg_c_x,a5),d0
  196.         move.w    (sg_c_y,a5),d1
  197.         add.w    #CHARWIDTH,(sg_c_x,a5)
  198.         bsr    _pc
  199.         bra    .nextkey
  200.  
  201. .bs        tst.w    d5
  202.         beq    .nextkey
  203.         bsr    _sg_cursoroff
  204.         subq.w    #1,d5
  205.         clr.b    (a3,d5.w)
  206.         bra    .chkname
  207.  
  208. .esc        bsr    _sg_cursoroff
  209.         lea    (sg_tmpname,a5),a0
  210.         move.l    a3,a1
  211. .cpy2        move.b    (a0)+,(a1)+
  212.         bne    .cpy2
  213.         bsr    _sg_initscr
  214.         bra    .start
  215.         
  216. .return        tst.w    d5            ;a name specified ?
  217.         beq    .esc
  218.         bsr    _sg_cursoroff
  219.  
  220.         moveq    #15,d1
  221.         lea    _saveconfirm,a0
  222.         bsr    _psc
  223.         
  224. .nextkey2    bsr    _sg_get_key
  225.         cmp.b    #$45,d0            ;escape
  226.         beq    .esc
  227.         cmp.b    #$43,d0            ;enter
  228.         beq    .confirmed
  229.         cmp.b    #$44,d0            ;return
  230.         bne    .nextkey2
  231.  
  232. .confirmed    lea    (sg_save_flags,a5),a0
  233.         st    (a0,d6.w)
  234.  
  235.         move.l    #SAVEDIRLEN,d0        ;size
  236.         moveq    #0,d1            ;offset
  237.         lea    (_sg_name),a0        ;filename
  238.         lea    (sg_save_id,a5),a1    ;address
  239.         move.w    #resload_SaveFileOffset,a2
  240.         bsr    _sg_exec_resload
  241.  
  242.         move.l    (sg_size,a5),d0        ;size
  243.         move.l    #SAVEDIRLEN,d1
  244.         bra    .loopin
  245. .loop        add.l    d0,d1            ;offset
  246. .loopin        subq.w    #1,d6
  247.         bpl    .loop
  248.         lea    (_sg_name),a0        ;filename
  249.         move.l    (sg_address,a5),a1    ;address
  250.         move.w    #resload_SaveFileOffset,a2
  251.         bsr    _sg_exec_resload
  252.  
  253.         st    (sg_success,a5)
  254.         bra    _sg_restore
  255.  
  256. ;--------------------------------
  257. ; disable text cursor
  258. ; IN:    -
  259. ; OUT:    -
  260.  
  261. _sg_cursoroff    sf    (sg_c_on,a5)
  262.         move.w    (sg_c_x,a5),d0
  263.         move.w    (sg_c_y,a5),d1
  264.         move.w    #' ',d2
  265.         bra    _pc
  266.  
  267. ;--------------------------------
  268. ; clear screen
  269. ; IN:    -
  270. ; OUT:    -
  271.  
  272. _sg_clrscr    movem.l    d0/a0,-(a7)
  273.  
  274.         move.l    (sg_screen,a5),a0
  275.         move.w    #(320*256/8)/4-1,d0
  276. .clr        clr.l    (a0)+
  277.         dbf    d0,.clr
  278.  
  279.         movem.l    (a7)+,d0/a0
  280.         rts
  281.  
  282. ;--------------------------------
  283. ; init screen
  284. ; IN:    -
  285. ; OUT:    -
  286.  
  287. _sg_initscr    movem.l    d0-d3/a0,-(a7)
  288.  
  289.         bsr    _sg_clrscr
  290.  
  291.     ;draw border
  292.     ;    moveq    #0,d0
  293.     ;    moveq    #0,d1
  294.     ;    move.w    #319,d2
  295.     ;    move.w    #199,d3
  296.     ;    bsr    _sg_rect
  297.     ;print info
  298.         move.w    #180,d1
  299.         lea    _info1,a0
  300.         bsr    _psc
  301.         add.w    #8,d1
  302.         lea    _info2,a0
  303.         bsr    _psc
  304.  
  305.         movem.l    (a7)+,d0-d3/a0
  306.         rts
  307.  
  308. ;--------------------------------
  309. ; load a savegame
  310. ; IN:    A0 = address to load savegame on
  311. ;    A1 = address of free memory for screen ($2800 bytes)
  312. ; OUT:    D0 = BOOL success
  313.  
  314. _sg_load    moveq    #-1,d1
  315.         bra    _sg_degrade
  316. _sg_load_in    bsr    _sg_loaddir
  317.         beq    .nosavegame
  318.  
  319. .start        moveq    #7,d1
  320.         lea    _load,a0
  321.         bsr    _psc
  322.         add.w    #8,d1
  323.         lea    _loadselect,a0
  324.         bsr    _psc
  325.         add.w    #8,d1
  326.         lea    _esc,a0
  327.         bsr    _psc
  328.         
  329.         bsr    _sg_printdir
  330.         
  331.         lea    (sg_save_names,a5),a0
  332.         moveq    #0,d0
  333.         
  334.  
  335. .keyloop    bsr    _sg_get_key
  336.         cmp.b    #$45,d0
  337.         beq    _sg_restore
  338.         
  339.         lea    (_keytrans),a0
  340.         moveq    #0,d1
  341.         move.b    (a0,d0.w),d1
  342.         cmp.b    #'1',d1
  343.         blo    .keyloop
  344.         cmp.b    #'9',d1
  345.         bhi    .keyloop
  346.         
  347.         lea    (sg_save_flags,a5),a0
  348.         tst.b    (-'1',a0,d1.w)
  349.         beq    .keyloop
  350.         
  351.         moveq    #XBASE+9,d0
  352.         sub.w    #'1',d1
  353.         move.w    d1,d6            ;D6 = save no.
  354.         mulu    #YSKIP,d1
  355.         add.w    #YBASE-5,d1
  356.         move.w    d0,d2
  357.         add.w    #210,d2
  358.         move.w    d1,d3
  359.         add.w    #YSKIP-1,d3
  360.         bsr    _sg_rect
  361.         
  362.         moveq    #15,d1
  363.         lea    _loadconfirm,a0
  364.         bsr    _psc
  365.         
  366. .nextkey2    bsr    _sg_get_key
  367.         cmp.b    #$43,d0            ;enter
  368.         beq    .confirmed
  369.         cmp.b    #$44,d0            ;return
  370.         beq    .confirmed
  371.         cmp.b    #$45,d0            ;escape
  372.         bne    .nextkey2
  373.         bsr    _sg_initscr
  374.         bra    .start
  375.  
  376. .confirmed    move.l    (sg_size,a5),d0        ;size
  377.         move.l    #SAVEDIRLEN,d1
  378.         bra    .loopin
  379. .loop        add.l    d0,d1            ;offset
  380. .loopin        subq.w    #1,d6
  381.         bpl    .loop
  382.         lea    (_sg_name),a0        ;filename
  383.         move.l    (sg_address,a5),a1    ;address
  384.         move.w    #resload_LoadFileOffset,a2
  385.         bsr    _sg_exec_resload
  386.  
  387.         st    (sg_success,a5)
  388.         bra    _sg_restore
  389.  
  390. .nosavegame    moveq    #60,d1
  391.         lea    _loadno1,a0
  392.         bsr    _psc
  393.         add.w    #8,d1
  394.         lea    _loadno2,a0
  395.         bsr    _psc
  396.         bsr    _sg_get_key
  397.         bra    _sg_restore
  398.  
  399. ;--------------------------------
  400. ; loads save directory
  401. ; IN:    -
  402. ; OUT:    D0 = BOOL success
  403. ;    flags on D0
  404.  
  405. _sg_loaddir    lea    (_sg_name),a0
  406.         move.w    #resload_GetFileSize,a2
  407.         bsr    _sg_exec_resload
  408.         tst.l    d0
  409.         beq    .nocurrentfile
  410.  
  411.         move.l    #SAVEDIRLEN,d0        ;size
  412.         moveq    #0,d1            ;offset
  413.         lea    (_sg_name),a0        ;filename
  414.         lea    (sg_save_id,a5),a1    ;address
  415.         move.w    #resload_LoadFileOffset,a2
  416.         bsr    _sg_exec_resload
  417.         cmp.l    #"Wepl",(sg_save_id,a5)
  418.         bne    .nocurrentfile
  419.         moveq    #-1,d0            ;successful loaded
  420.         rts
  421.  
  422. .nocurrentfile    lea    (sg_save_id,a5),a0
  423.         move.w    #SAVEDIRLEN/4-1,d0
  424. .clr0        clr.l    (a0)+
  425.         dbf    d0,.clr0
  426.         move.l    #"Wepl",(sg_save_id,a5)
  427.         moveq    #0,d0            ;nothing current
  428.         rts
  429.  
  430. ;--------------------------------
  431. ; execute resload function
  432.  
  433. _sg_exec_resload
  434.         move.w    #INTF_INTEN,(intena,a6)
  435.         add.l    (_resload),a2
  436.         jsr    (a2)
  437.         move.w    #INTF_SETCLR!INTF_INTEN,(intena,a6)
  438.         clr.l    ($144,a6)
  439.         clr.l    ($14c,a6)
  440.         rts
  441.  
  442. ;--------------------------------
  443.  
  444. _sg_get_key    clr.b    (sg_key,a5)
  445.         moveq    #0,d0
  446. .waitdown    move.b    (sg_key,a5),d0
  447.         ble    .waitdown
  448.         bchg    #7,d0
  449. .waitup        cmp.b    (sg_key,a5),d0
  450.         bne    .waitup
  451.         bclr    #7,d0
  452.         rts
  453.  
  454. ;--------------------------------
  455.  
  456. _sg_degrade    movem.l    d2-d7/a2-a6,-(a7)
  457.         link    a5,#sg_SIZEOF            ;A5 = data
  458.         move.l    d0,(sg_size,a5)
  459.         move.l    a0,(sg_address,a5)
  460.         move.l    a1,(sg_screen,a5)
  461.         sf    (sg_c_on,a5)
  462.         sf    (sg_success,a5)
  463.         bsr    _sg_waitvb
  464.         move.w    (_custom+intenar),(sg_oldintena,a5)
  465.         move.w    #$7fff,(_custom+intena)
  466.         lea    (_custom),a6            ;A6 = _custom
  467.         move.w    (dmaconr,a6),(sg_olddmacon,a5)
  468.         move.w    #$7fff,(dmacon,a6)
  469.         bsr    _sg_initscr
  470.         lea    (_sg_int68),a0
  471.         move.l    $68,(sg_old68,a5)
  472.         move.l    a0,$68
  473.         lea    (_sg_int6c),a0
  474.         move.l    $6c,(sg_old6c,a5)
  475.         move.l    a0,$6c
  476.         move.w    #INTF_SETCLR|INTF_INTEN|INTF_VERTB|INTF_PORTS,(intena,a6)
  477.         tst.b    (ciaicr+_ciaa)            ;clear all intreq
  478.         move.w    #INTF_VERTB|INTF_PORTS,(intreq,a6)
  479.         bsr    _sg_waitvb
  480.         move.w    #$1200,(bplcon0,a6)
  481.         clr.w    (bpl1mod,a6)
  482.         move.l    #$00000eee,(color,a6)
  483.         move.w    #DMAF_SETCLR|DMAF_MASTER|DMAF_RASTER,(dmacon,a6)
  484.         tst.l    d1
  485.         beq    _sg_save_in
  486.         bra    _sg_load_in
  487.  
  488. ;--------------------------------
  489.  
  490. _sg_restore    bsr    _sg_clrscr
  491.         move.b    (sg_success,a5),d0
  492.         ext.w    d0
  493.         move.w    d0,a0                ;a0 = success
  494.         bsr    _sg_waitvb
  495.         move.w    #$7fff,(intena,a6)
  496.         move.w    #$7fff,(dmacon,a6)
  497.         move.l    (sg_old68,a5),$68
  498.         move.l    (sg_old6c,a5),$6c
  499.         move.w    #$7fff,(intreq,a6)
  500.         move.w    (sg_oldintena,a5),d0
  501.         bset    #15,d0                ;d0 = intena
  502.         move.w    (sg_olddmacon,a5),d1
  503.         bset    #15,d1                ;d1 = dmacon
  504.         unlk    a5
  505.         movem.l    (a7)+,d2-d7/a2-a6
  506.         move.w    d0,(_custom+intena)
  507.         bsr    _sg_waitvb
  508.         move.w    d1,(_custom+dmacon)
  509.         move.l    a0,d0                ;success
  510.         rts
  511.  
  512. ;--------------------------------
  513.  
  514. _sg_int68    movem.l    d0-d1,-(a7)
  515.         btst    #CIAICRB_SP,(ciaicr+_ciaa)    ;check int reason
  516.         beq    .int2_exit
  517.         move.b    (ciasdr+_ciaa),d0        ;read code
  518.         clr.b    (ciasdr+_ciaa)            ;output LOW (handshake)
  519.         or.b    #CIACRAF_SPMODE,(ciacra+_ciaa)    ;to output
  520.         not.b    d0
  521.         ror.b    #1,d0
  522.         cmp.b    (_keyexit),d0
  523.         beq    _exit
  524.         move.b    d0,(sg_key,a5)
  525.         moveq    #3-1,d1                ;wait because handshake min 75 µs
  526. .int2_w1    move.b    (vhposr,a6),d0
  527. .int2_w2    cmp.b    (vhposr,a6),d0            ;one line is 63.5 µs
  528.         beq    .int2_w2
  529.         dbf    d1,.int2_w1            ;(min=127µs max=190.5µs)
  530.         and.b    #~(CIACRAF_SPMODE),(ciacra+_ciaa)    ;to input
  531. .int2_exit    move.w    #INTF_PORTS,(intreq,a6)
  532.         movem.l    (a7)+,d0-d1
  533.         rte
  534.  
  535. ;--------------------------------
  536.  
  537. _sg_int6c    move.l    (sg_screen,a5),(bplpt,a6)
  538.         tst.b    (sg_c_on,a5)
  539.         beq    .1
  540.         movem.l    d0-d2,-(a7)
  541.         move.w    (sg_c_x,a5),d0
  542.         move.w    (sg_c_y,a5),d1
  543.         move.w    #' ',d2
  544.         bchg    #0,(sg_c_on,a5)
  545.         beq    .2
  546.         move.w    #'_',d2
  547. .2        bsr    _pc
  548.         movem.l    (a7)+,d0-d2
  549. .1        move.w    #INTF_VERTB,(intreq,a6)
  550.         rte
  551.  
  552. ;--------------------------------
  553.  
  554. _sg_waitvb    waitvb
  555.         rts
  556.  
  557. ;--------------------------------
  558. ; draw rectangle
  559. ; IN:    d0 = word x start
  560. ;    d1 = word y start
  561. ;    d2 = word x stop
  562. ;    d3 = word y stop
  563. ; OUT:    -
  564.  
  565. _sg_rect    bsr    _sg_xline
  566.         exg    d1,d3
  567.         bsr    _sg_xline
  568.         exg    d1,d2
  569.         exg    d1,d3
  570.         bsr    _sg_yline
  571.         exg    d0,d3
  572.         bra    _sg_yline
  573.  
  574. ;--------------------------------
  575. ; line in x axis
  576. ; IN:    d0 = word x start
  577. ;    d1 = word y start
  578. ;    d2 = word x stop
  579. ; OUT:    -
  580.  
  581. _sg_xline    movem.l    d0/d2,-(a7)
  582.         cmp.w    d0,d2
  583.         beq    .end
  584.         bhi    .in
  585.         exg    d0,d2
  586.         bra    .in
  587. .next        addq.w    #1,d0
  588. .in        bsr    _sg_pset
  589.         cmp.w    d0,d2
  590.         bne    .next
  591. .end        movem.l    (a7)+,d0/d2
  592.         rts
  593.  
  594. ;--------------------------------
  595. ; line in y axis
  596. ; IN:    d0 = word x start
  597. ;    d1 = word y start
  598. ;    d2 = word y stop
  599. ; OUT:    -
  600.  
  601. _sg_yline    movem.l    d1/d2,-(a7)
  602.         cmp.w    d1,d2
  603.         beq    .end
  604.         bhi    .in
  605.         exg    d1,d2
  606.         bra    .in
  607. .next        addq.w    #1,d1
  608. .in        bsr    _sg_pset
  609.         cmp.w    d1,d2
  610.         bne    .next
  611. .end        movem.l    (a7)+,d1/d2
  612.         rts
  613.  
  614. ;--------------------------------
  615. ; set a pixel
  616. ; IN:    d0 = word x start
  617. ;    d1 = word y start
  618. ; OUT:    -
  619.  
  620. _sg_pset    move.l    d1,-(a7)
  621.         bsr    _getscrptr
  622.         move.w    d0,d1
  623.         lsr.w    #3,d1
  624.         add.w    d1,a0
  625.         moveq    #7,d1
  626.         and.w    d0,d1
  627.         neg.w    d1
  628.         addq.w    #7,d1
  629.         bset    d1,(a0)
  630.         move.l    (a7)+,d1
  631.         rts
  632.  
  633. ;--------------------------------
  634. ; IN:    d1 = word y start
  635. ; OUT:    a0 = ptr
  636.  
  637. _getscrptr    move.l    (sg_screen,a5),a0
  638.         mulu    #LINE,d1
  639.         add.l    d1,a0
  640.         rts
  641.         
  642. ;--------------------------------
  643. ; print string centered
  644. ; IN:    d1 = word y
  645. ;    a0 = cptr string
  646. ; OUT:    d0 = word new x
  647.  
  648. _psc        move.l    a0,-(a7)
  649.         moveq    #0,d0
  650. .count        tst.b    (a0)+
  651.         beq    .1
  652.         subq.w    #CHARWIDTH,d0
  653.         bra    .count
  654. .1        asr.w    #1,d0
  655.         add.w    #LINE*4,d0
  656.         move.l    (a7)+,a0
  657.         bra    _ps
  658.  
  659. ;--------------------------------
  660. ; print string
  661. ; IN:    d0 = word x
  662. ;    d1 = word y
  663. ;    a0 = cptr string
  664. ; OUT:    d0 = word new x
  665.  
  666. _ps        movem.l    d2,-(a7)
  667.         moveq    #0,d2
  668.         bra    .in
  669. .next        bsr    _pc
  670.         add.w    #CHARWIDTH,d0
  671. .in        move.b    (a0)+,d2
  672.         bne    .next
  673.         movem.l    (a7)+,d2
  674.         rts
  675.  
  676. ;--------------------------------
  677. ; print char
  678. ; IN:    d0 = word x
  679. ;    d1 = word y
  680. ;    d2 = char
  681.  
  682. _pc        movem.l    d0-d5/a0-a1,-(a7)
  683.         bsr    _getscrptr
  684.         sub.w    #32,d2
  685.         mulu    #CHARWIDTH,d2
  686.         lea    (_font),a1
  687.         moveq    #CHARHEIGHT-1,d3
  688. .cp
  689.     IFD _68020_
  690.         bfextu    (a1){d2:CHARWIDTH},d1
  691.         bfins    d1,(a0){d0:CHARWIDTH}
  692.     ELSE
  693.         move.l    d2,d1
  694.         lsr.l    #4,d1                ;words
  695.         add.l    d1,d1                ;bytes down rounded to word
  696.         move.l    (a1,d1.l),d1
  697.         move.l    d2,d4
  698.         and.w    #%1111,d4
  699.         lsl.l    d4,d1
  700.         and.l    #$ffffffff<<(32-CHARWIDTH),d1
  701.         move.l    #$ffffffff>>CHARWIDTH,d5
  702.         move.l    d0,d4
  703.         and.w    #%1111,d4
  704.         lsr.l    d4,d1
  705.         ror.l    d4,d5
  706.         move.l    d0,d4
  707.         lsr.l    #4,d4                ;words
  708.         add.l    d4,d4                ;bytes down rounded to word
  709.         and.l    d5,(a0,d4.l)
  710.         or.l    d1,(a0,d4.l)
  711.     ENDC
  712.         add.l    #(_font_-_font)*8/CHARHEIGHT,d2
  713.         add.l    #LINE*8,d0
  714.         dbf    d3,.cp
  715.         movem.l    (a7)+,d0-d5/a0-a1
  716.         rts
  717.  
  718. _font        INCBIN    pics/pic_font_5x6_br.bin
  719. _font_
  720.  
  721. ;--------------------------------
  722.  
  723. _sg_name    dc.b    "savegame",0
  724. _info1        dc.b    "special multiple savegame support",0
  725. _info2        dc.b    "written by wepl in spring 1998",0
  726. _esc        dc.b    "press esc to cancel",0
  727. _save        dc.b    ">>> save a game <<<",0
  728. _saveselect    dc.b    "select a save position using the keyboard '1' - '9'",0
  729. _saveinsert    dc.b    "    type in a description for this save position    ",0
  730. _saveconfirm    dc.b    "        confirm this save operation (return)        ",0
  731. _load        dc.b    ">>> load a game <<<",0
  732. _loadselect    dc.b    "select a load position using the keyboard '1' - '9'",0
  733. _loadconfirm    dc.b    "        confirm this load operation (return)        ",0
  734. _loadno1    dc.b    "sorry there is currently no valid savegame to load",0
  735. _loadno2    dc.b    "press any key to continue",0
  736.  
  737. _keytrans    dc.b    0,"1234567890",0,0,"0",0,0
  738.         dc.b    "qwertyuiop",0,0,0,"123"
  739.         dc.b    "asdfghjkl",0,0,0,0,"456"
  740.         dc.b    0,"zxcvbnm,.-",0,0,"789"
  741.         dc.b    " ",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  742.         dc.b    "123456789",0,0,0,0,0,0,0
  743.         ds.b    16
  744.         ds.b    16
  745.  
  746.